package com.dukla.picbak.utils;

import io.minio.*;
import io.minio.messages.Tags;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

@Component
public class MinioUtil {

    private static final Logger logger = LoggerFactory.getLogger(MinioUtil.class);

    @Autowired
    private MinioClient minioClient;

    /**
     * 判断桶是否存在
     */
    public boolean existsBucket(String name) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
        } catch (Exception e) {
           logger.error(e.getMessage(),e);
           return false;
        }
    }

    /**
     * 创建桶
     */
    public void createBucket(String bucketName){
        try {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    /**
     * 创建目录
     */
    public void createDir(String bucketName,String dir){
        try {
            //minioClient.
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    /**
     * 保存字节数组对象到桶
     */
    public void saveByteArrayObject(String bucketName,String fileName,byte[] content){
        logger.info("Start save byte array object:{} to {}",fileName,bucketName);
        ByteArrayInputStream bin=new ByteArrayInputStream(content);
        try {
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(bin,bin.available(),-1)
                    .contentType("application/octet-stream")
                    .build());
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        logger.info("End save byte array object:{} to {}",fileName,bucketName);
    }

    /**
     * 保存字节流对象到桶
     */
    public void saveInputStreamObjectWithTag(String bucketName, String fileName, InputStream in,Map<String,String> tags){
        logger.info("Start save input stream object:{} to {}",fileName,bucketName);
        try {
            if(!ObjectUtils.isEmpty(tags)){
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .stream(in,in.available(),-1)
                        .userMetadata(tags)
                        .contentType("application/octet-stream")
                        .build());
            }else{
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .stream(in,in.available(),-1)
                        .contentType("application/octet-stream")
                        .build());
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        logger.info("End save input stream object:{} to {}",fileName,bucketName);
    }

    public void saveInputStreamObject(String bucketName, String fileName, InputStream in){
        this.saveInputStreamObjectWithTag(bucketName,fileName,in,null);
    }


    /**
     * 获取文件对象
     */
    public byte[] getFileObject(String bucketName,String fileName){
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        logger.info("Start get file object:{} from {}",fileName,bucketName);
        try {
            GetObjectResponse response = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .build());
            int v;
            while ((v=response.read()) != -1){
                bos.write(v);
            }

        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        logger.info("End get file object:{} from {}",fileName,bucketName);
        return bos.toByteArray();
    }


}
